/*
使用RSA公钥进行加密，RSA算法是使用整数进行加密运算。
计算密文的公式是： m*e mod n 其中e为对应的整数，n用于取模的整数，m为明文数字
明文为一个字符串，先转化为byte[]数组，然后转化为一个整数，并对其进行分组，整型数m的值必须小于n。
 */
import java.io.*;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;

public class RSA_Use {
    //生成公钥、私钥。
    public static void produceRSAKey() throws Exception {
        KeyPairGenerator kpg=KeyPairGenerator.getInstance("RSA");//创建密钥生成器
        kpg.initialize(1024);//初始化密钥生成器
        KeyPair kp=kpg.genKeyPair();//生成密钥对
        PublicKey pbkey=kp.getPublic();//获取公钥
        PrivateKey prkey=kp.getPrivate();//获取私钥
        //  保存公钥
        FileOutputStream f1=new FileOutputStream("Skey_RSA_pub.dat");
        ObjectOutputStream b1=new  ObjectOutputStream(f1);
        b1.writeObject(pbkey);
        //  保存私钥
        FileOutputStream  f2=new FileOutputStream("Skey_RSA_priv.dat");
        ObjectOutputStream b2=new  ObjectOutputStream(f2);
        b2.writeObject(prkey);
        System.out.println("RSA公钥、私钥生成完成");
    }
    //使用RSA的公钥加密DES的密钥。
    public static BigInteger EncryptionRSA(BigInteger m) throws Exception {
        FileInputStream f=new FileInputStream("Skey_RSA_pub.dat");
        ObjectInputStream b=new ObjectInputStream(f);
        RSAPublicKey pbk=(RSAPublicKey)b.readObject( );
        BigInteger e=pbk.getPublicExponent();//获取公钥的参数e,n。
        BigInteger n=pbk.getModulus();
        System.out.println("e= "+e);
        System.out.println("n= "+n);
        // 明文 m
        // 计算密文c,打印
        BigInteger c=m.modPow(e,n);
        //System.out.println("c= "+c);
        // 保存密文
        String cs=c.toString( );//以字符串的形式保存
        BufferedWriter out=
                new BufferedWriter(new OutputStreamWriter(
                        new FileOutputStream("Enc_RSA.dat")));
        out.write(cs,0,cs.length( ));
        out.close( );
        System.out.println("使用RSA加密完成");
        return c;
    }
    //使用RSA的私钥解密。得到DES的密钥，保存在文件中
    public static Key  DecryptionRSA(BigInteger c)throws Exception {
        //读取私钥
        FileInputStream f = new FileInputStream("Skey_RSA_priv.dat");
        ObjectInputStream b = new ObjectInputStream(f);
        RSAPrivateKey prk = (RSAPrivateKey) b.readObject();
        BigInteger d = prk.getPrivateExponent();
        //获取私钥参数及解密,私钥对应的整数d和用于取模的整数n
        BigInteger n = prk.getModulus();
        System.out.println("d= " + d);
        System.out.println("n= " + n);
        BigInteger m = c.modPow(d, n);
        //显示解密结果
        System.out.println("m= " + m);
        byte[] mt = m.toByteArray();



        BigInteger bigInteger = new BigInteger(mt);
        FileOutputStream fileOutputStream = new FileOutputStream("hh.dat");//指定产生密钥输出流文件
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);//将对象序列化，以流的方式进行处理
        objectOutputStream.writeObject(bigInteger);//通过以对象序列化方式将密钥保存在文件中
        FileInputStream fileInputStream = new FileInputStream("hh.dat");
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
        Key key = (Key) objectInputStream.readObject();
        return key;
    }
}

